
#ifndef SCRIPTSTUDIO_H
#define SCRIPTSTUDIO_H

#include <BSet>
#include <BMap>
#include <BWidget>
#include <BImage>
#include <BSlider>
#include <BTabWidget>
#include <BTreeWidget>
#include <BSonDocument>
#include <BTextEdit>
#include <BMenu>
#include <BLabel>
#include <BButton>
#include <BLineEdit>
#include <BComboBox>
#include <BSplitButton>
#include <BHBoxLayout>
#include <BClass>
#include <BScript>
#include <BMainWindow>

#include "ScriptThread.h"
#include "SearchDialog.h"
#include "ScriptPropertyDialog.h"
#include "SourceEdit.h"
#include "StatusBoard.h"
#include "ScriptBrowser.h"

class ScriptStudio : public BMainWindow
{
	BOBJECT(ScriptStudio)
public:
	ScriptStudio();
	~ScriptStudio();

	bool loadProject(const BString& fileName);
	bool saveProject(const BString& fileName);

protected:
	void initScript(BScript* script);
	BTreeItem* createScriptItem(BScript* script);
	BTreeItem* createSourceItem(BSource* source);
	BScript* scriptOfFolder(BFolder* folder);
	BWidget* openTreeItem(BTreeItem* item);
	void freshTreeItem(BTreeItem* item);
	void drawTreeItem(BPainter& painter, BTreeItem* item);

	void resetChanged(BWidget* widget);
	void signChanged(BWidget* widget);

	bool checkOpenAction(const BTreeItemArray& selection);
	bool checkBuildAction(const BTreeItemArray& selection);

	bool saveFile();
	bool saveAllFiles();

	bool startBuilding();
	bool abortBuilding();
	bool finishBuilding();

	void collectDepends(BExp* exp, SourceInfo* srcinfo);
	void dirtyDependSource(const BString& header);
	void jumpToBreakpoint(BScript* script);
	void updateEntrance(BScript* script);
	void freshScriptStack(BScript* script);
	BObject* createMenuOrAction(const BString& type, const BString& name, const BValue& value);

protected:
	void slotOpenActionTrigger(BAction* action);
	void slotBuildActionTriggered(BAction* action);
	void slotAddFileActionTrigger(BAction* action);
	void slotAddFolderActionTrigger(BAction* action);
	void slotAddScriptActionTrigger(BAction* action);
	void slotNewFileActionTrigger(BAction* action);
	void slotNewScriptActionTrigger(BAction* action);
	void slotNewFolderActionTrigger(BAction* action);
	void slotRemoveActionTrigger(BAction* action);
	void slotBrowseActionTrigger(BAction* action);
	void slotSettingActionTrigger(BAction* action, const BValue& value);
	void slotShowPunctMenuChecked(BMenu* menu, const BValue& value);
	void slotShowPunctMenuTriggered(BMenu* menu, const BValue& value);

	void slotOpenButtonClicked();
	void slotSaveButtonClicked();
	void slotSaveAllButtonClicked();
	void slotUndoButtonClicked();
	void slotRedoButtonClicked();
	void slotSearchButtonToggled(BObject* object, const BValue& value);
	void slotSearchDialogHide(BObject* object, const BValue& value);

	void slotBuildButtonToggled(BObject* object, const BValue& value);
	void slotCallButtonToggled(BObject* object, const BValue& value);
	void slotDebugResetButtonClicked(BObject* object, const BValue& value);
	void slotDebugRunButtonClicked(BObject* object, const BValue& value);
	void slotDebugNextButtonClicked();
	void slotDebugStepButtonClicked();
	void slotDebugFunctionChanged(BObject* object, const BValue& value);
	void slotDebugEditKeyPressed(BTextEdit* textEdit, const BValue& value);

	void slotFolderNotifying(BFolder* folder, const BValue& value);
	void slotScriptDebugging(BObject* object, const BValue& value);
	void slotScriptCompiled(BScript* script, const BValue& value);
	void slotScriptMessage(BScript* script, const BValue& value);
	void slotScriptBreaked(BScript* script, const BValue& value);
	void slotScriptInited(BScript* script, const BValue& value);
	void slotScriptError(BScript* script, const BValue& value);
	void slotSourceMessage(BSource* source, const BValue& value);

	void slotTreeWidgetStyled(BObject* object, const BValue& value);
	void slotTreeWidgetFramed(BObject* object, const BValue& value);
	void slotTreeItemClicked(BObject* object, const BValue& value);
	void slotTreeItemDoubleClicked(BObject* object, const BValue& value);
	void slotTreeSelectionChanged(BObject* object, const BValue& value);
	void slotTreeWidgetRightClicked(BObject* object, const BValue& value);
	void slotTreeWidgetDragDropped(BObject* object, const BValue& value);

	void slotItemEditFocused(BObject* object, const BValue& value);
	void slotItemTextEdited(BObject* object, const BValue& value);
	void slotItemEditFinished(BObject* object, const BValue& value);

	void slotCurrentTabChanged(BObject* object, const BValue& value);
	void slotSourceTextEdited(BObject* object, const BValue& vlaue);
	void slotTextEditFramed(BTextEdit* textEdit, const BValue& vlaue);
	void slotTextEditRightClicked(BTextEdit* textEdit, const BValue& vlaue);
	void slotOutputDoubleClicked(BObject* object, const BValue& value);
	void slotCreateBreakpoint(BObject* object, const BValue& value);
	void slotRemoveBreakpoint(BObject* object, const BValue& value);
	void slotGotoDefinition(BObject* object, const BValue& value);
	void slotGotoDeclaration(BObject* object, const BValue& value);

protected:
	virtual void showEvent(const BEvent& event);
	virtual void closeEvent(const BEvent& event);

	virtual void resizeEvent(const BEvent& event);
	virtual void updateEvent(const BEvent& event);

	virtual void styleEvent(const BEvent& event);
	virtual void freshEvent(const BEvent& event);
	virtual void paintEvent(const BEvent& event);

private:
	BMenu*				_itemMenu;
	BActionHolder		_openAction;
	BActionHolder		_buildAction;
	BMenuHolder			_addMenu;
	BActionHolder		_addFileAction;
	BActionHolder		_addFolderAction;
	BActionHolder		_addScriptAction;
	BMenuHolder			_newMenu;
	BActionHolder		_newFileAction;
	BActionHolder		_newFolderAction;
	BActionHolder		_newScriptAction;
	BActionHolder		_removeAction;
	BActionHolder		_browseAction;
	BActionHolder		_settingAction;

	BMenuHolder			_editMenu;

	BWidget*			_toolBar;
	BButton*			_openButton;
	BButton*			_saveButton;
	BButton*			_saveAllButton;
	BButton*			_undoButton;
	BButton*			_redoButton;
	BButton*			_searchButton;
	BButton*			_viewButton;
	BButton*			_buildButton;
	BSplitButton*		_callButton;
	BButton*			_debugRunButton;
	BButton*			_debugNextButton;
	BButton*			_debugStepButton;
	BButton*			_debugResetButton;
	BComboBox*			_functionComboBox;
	BHBoxLayout*		_debugLayout;
	BHBoxLayout*		_paramsLayout;

	BTreeWidget*		_treeWidget;
	StatusBoard*		_statusBoard;
	BTabWidget*			_editTabWidget;
	BTabWidget*			_bottomTabWidget;
	BHolder<SearchDialog>	_searchDialog;
	BHolder<BTreeWidget>	_searchBoard;

	BHolder<BButton>		_variantButton;
	BLineEdit*				_itemEdit;
	BPoint					_pressedPos;
	BString					_fileName;
	BHolder<ScriptThread>	_scriptThread;

	typedef BMap<BTreeItem*, bool> BuildTaskMap;
	BuildTaskMap::iterator	_buildTask;
	BuildTaskMap			_buildTaskMap;

	BString					_breakpoint;
	BHolder<BTextEdit>		_breakTextEdit;
	int						_breakLineNumber;

	BImageHolder		_arrowImage;
	BImageHolder		_dirtyImage;
	BImageHolder		_lostImage;
};

#endif